package actor

import (
	"context"
	"fmt"
	"sync"
	"time"

	"github.com/louloulin/dataflare/pkg/actor/lifecycle"
	"github.com/louloulin/dataflare/pkg/plugin"
)

// WasmPluginManagerMessages 定义了WASM插件管理器Actor的消息类型
type WasmPluginManagerMessages struct{}

// LoadPluginMessage 加载插件消息
type LoadPluginMessage struct {
	PluginID        string
	PluginDirectory string
	Config          map[string]interface{}
}

// UnloadPluginMessage 卸载插件消息
type UnloadPluginMessage struct {
	PluginID string
}

// ListPluginsMessage 列出插件消息
type ListPluginsMessage struct{}

// ListPluginsResponse 列出插件响应
type ListPluginsResponse struct {
	Plugins []PluginInfo
}

// GetPluginMessage 获取插件消息
type GetPluginMessage struct {
	PluginID string
}

// GetPluginResponse 获取插件响应
type GetPluginResponse struct {
	Plugin     plugin.Plugin
	PluginInfo PluginInfo
	Actor      *WasmPluginActor
	Found      bool
}

// GetAllPluginsMessage 获取所有插件消息
type GetAllPluginsMessage struct{}

// GetAllPluginsResponse 获取所有插件响应
type GetAllPluginsResponse struct {
	PluginInfos []PluginInfo
}

// PluginInfo 包含插件的基本信息
type PluginInfo struct {
	ID          string
	Name        string
	Type        plugin.PluginType
	Version     string
	Description string
}

// WasmPluginManagerActor 表示一个WASM插件管理器Actor
type WasmPluginManagerActor struct {
	lifecycle.LifecycleAwareActor
	plugins      map[string]plugin.Plugin
	pluginActors map[string]*WasmPluginActor
	pluginLoader *plugin.WasmPluginLoader
	pluginDir    string
	lastLoadTime time.Time
	mu           sync.RWMutex
}

// NewWasmPluginManagerActor 创建一个新的WASM插件管理器Actor
func NewWasmPluginManagerActor(pluginDir string) *WasmPluginManagerActor {
	actor := &WasmPluginManagerActor{
		plugins:      make(map[string]plugin.Plugin),
		pluginActors: make(map[string]*WasmPluginActor),
		pluginDir:    pluginDir,
		pluginLoader: plugin.NewWasmPluginLoader(pluginDir),
	}

	// 初始化生命周期相关属性
	actor.Initialize("wasm_plugin_manager")

	return actor
}

// OnInit 初始化插件管理器
func (a *WasmPluginManagerActor) OnInit() error {
	// 调用基类方法
	if err := a.LifecycleAwareActor.OnInit(); err != nil {
		return err
	}

	// 扫描插件目录
	return nil
}

// OnStart 启动插件管理器
func (a *WasmPluginManagerActor) OnStart() error {
	// 调用基类方法
	if err := a.LifecycleAwareActor.OnStart(); err != nil {
		return err
	}

	// 可以在此添加额外的启动逻辑
	return nil
}

// OnStop 停止插件管理器
func (a *WasmPluginManagerActor) OnStop() error {
	// 调用基类方法
	if err := a.LifecycleAwareActor.OnStop(); err != nil {
		return err
	}

	// 停止所有插件
	a.mu.Lock()
	defer a.mu.Unlock()

	for _, pluginActor := range a.pluginActors {
		if err := pluginActor.OnStop(); err != nil {
			a.RecordError(err)
			// 继续停止其他插件，不中断
		}
	}

	return nil
}

// HandleLoadPlugin 处理加载插件消息
func (a *WasmPluginManagerActor) HandleLoadPlugin(msg *LoadPluginMessage) error {
	a.mu.Lock()
	defer a.mu.Unlock()

	a.RecordMessageReceived()

	// 如果指定了插件ID，尝试精确加载
	if msg.PluginID != "" {
		// 检查插件是否已加载
		if _, exists := a.plugins[msg.PluginID]; exists {
			return fmt.Errorf("plugin %s already loaded", msg.PluginID)
		}

		// 加载指定的插件
		pluginDir := a.pluginDir
		if msg.PluginDirectory != "" {
			pluginDir = msg.PluginDirectory
		}

		loader := plugin.NewWasmPluginLoader(pluginDir)
		ctx := context.Background()
		plugins, err := loader.LoadWasmPlugins(ctx)
		if err != nil {
			a.RecordError(err)
			return fmt.Errorf("failed to load plugin %s: %w", msg.PluginID, err)
		}

		// 尝试从加载的插件中找到我们需要的
		var pluginInstance plugin.Plugin
		for _, p := range plugins {
			if p.ID() == msg.PluginID {
				pluginInstance = p
				break
			}
		}

		if pluginInstance == nil {
			return fmt.Errorf("plugin %s not found in directory %s", msg.PluginID, pluginDir)
		}

		// 创建插件Actor
		pluginActor := NewWasmPluginActor(pluginInstance)

		// 初始化插件
		if msg.Config != nil {
			if err := pluginActor.HandleInitMessage(&InitPluginMessage{Config: msg.Config}); err != nil {
				a.RecordError(err)
				return fmt.Errorf("failed to initialize plugin %s: %w", msg.PluginID, err)
			}
		}

		// 启动插件
		if err := pluginActor.OnStart(); err != nil {
			a.RecordError(err)
			return fmt.Errorf("failed to start plugin %s: %w", msg.PluginID, err)
		}

		// 添加到管理的插件列表
		a.plugins[msg.PluginID] = pluginInstance
		a.pluginActors[msg.PluginID] = pluginActor

		a.lastLoadTime = time.Now()
		return nil
	}

	// 否则，加载目录中的所有插件
	pluginDir := a.pluginDir
	if msg.PluginDirectory != "" {
		pluginDir = msg.PluginDirectory
	}

	loader := plugin.NewWasmPluginLoader(pluginDir)
	ctx := context.Background()
	plugins, err := loader.LoadWasmPlugins(ctx)
	if err != nil {
		a.RecordError(err)
		return fmt.Errorf("failed to load plugins from directory %s: %w", pluginDir, err)
	}

	for _, pluginInstance := range plugins {
		// 跳过已加载的插件
		pluginID := pluginInstance.ID()
		if _, exists := a.plugins[pluginID]; exists {
			continue
		}

		// 创建插件Actor
		pluginActor := NewWasmPluginActor(pluginInstance)

		// 初始化插件
		if msg.Config != nil {
			if err := pluginActor.HandleInitMessage(&InitPluginMessage{Config: msg.Config}); err != nil {
				a.RecordError(err)
				// 继续加载其他插件，不中断
				continue
			}
		}

		// 启动插件
		if err := pluginActor.OnStart(); err != nil {
			a.RecordError(err)
			// 继续加载其他插件，不中断
			continue
		}

		// A 添加到管理的插件列表
		a.plugins[pluginID] = pluginInstance
		a.pluginActors[pluginID] = pluginActor
	}

	a.lastLoadTime = time.Now()
	return nil
}

// HandleUnloadPlugin 处理卸载插件消息
func (a *WasmPluginManagerActor) HandleUnloadPlugin(msg *UnloadPluginMessage) error {
	a.mu.Lock()
	defer a.mu.Unlock()

	a.RecordMessageReceived()

	// 检查插件是否存在
	pluginActor, exists := a.pluginActors[msg.PluginID]
	if !exists {
		return fmt.Errorf("plugin %s not found", msg.PluginID)
	}

	// 停止插件
	if err := pluginActor.OnStop(); err != nil {
		a.RecordError(err)
		// 继续卸载，不中断
	}

	// 从管理列表中移除
	delete(a.plugins, msg.PluginID)
	delete(a.pluginActors, msg.PluginID)

	return nil
}

// HandleListPlugins 处理列出插件消息
func (a *WasmPluginManagerActor) HandleListPlugins(msg *ListPluginsMessage) (*ListPluginsResponse, error) {
	a.mu.RLock()
	defer a.mu.RUnlock()

	a.RecordMessageReceived()

	var pluginInfos []PluginInfo
	for _, p := range a.plugins {
		info := PluginInfo{
			ID:          p.ID(),
			Name:        p.Name(),
			Type:        p.Type(),
			Version:     p.Version(),
			Description: p.Description(),
		}
		pluginInfos = append(pluginInfos, info)
	}

	return &ListPluginsResponse{
		Plugins: pluginInfos,
	}, nil
}

// HandleGetPlugin 处理获取插件消息
func (a *WasmPluginManagerActor) HandleGetPlugin(msg *GetPluginMessage) (*GetPluginResponse, error) {
	a.mu.RLock()
	defer a.mu.RUnlock()

	a.RecordMessageReceived()

	p, exists := a.plugins[msg.PluginID]
	if !exists {
		return &GetPluginResponse{
			Found: false,
		}, nil
	}

	actor := a.pluginActors[msg.PluginID]
	info := PluginInfo{
		ID:          p.ID(),
		Name:        p.Name(),
		Type:        p.Type(),
		Version:     p.Version(),
		Description: p.Description(),
	}

	return &GetPluginResponse{
		Plugin:     p,
		PluginInfo: info,
		Actor:      actor,
		Found:      true,
	}, nil
}

// GetMetrics 获取插件管理器度量指标
func (a *WasmPluginManagerActor) GetMetrics() map[string]interface{} {
	a.mu.RLock()
	defer a.mu.RUnlock()

	pluginCount := len(a.plugins)
	runningCount := 0

	for _, actor := range a.pluginActors {
		if actor.IsRunning() {
			runningCount++
		}
	}

	metrics := map[string]interface{}{
		"id":                "wasm_plugin_manager",
		"state":             string(a.State),
		"plugin_count":      pluginCount,
		"running_count":     runningCount,
		"messages_received": a.Metrics.MessagesReceived,
		"messages_sent":     a.Metrics.MessagesSent,
		"error_count":       a.Metrics.ErrorCount,
	}

	if a.Metrics.ErrorCount > 0 {
		metrics["last_error"] = a.Metrics.LastError
	}

	if !a.lastLoadTime.IsZero() {
		metrics["last_load_time"] = a.lastLoadTime.Format(time.RFC3339)
	}

	return metrics
}

// String 返回插件管理器Actor的字符串表示
func (a *WasmPluginManagerActor) String() string {
	metrics := a.GetMetrics()

	return fmt.Sprintf("WasmPluginManagerActor[state=%s, plugins=%d, running=%d]",
		a.State, metrics["plugin_count"], metrics["running_count"])
}

// GetPluginInfo 获取插件信息
func (a *WasmPluginManagerActor) GetPluginInfo(pluginID string) *PluginInfo {
	for _, p := range a.plugins {
		if p.ID() == pluginID {
			info := &PluginInfo{
				ID:          p.ID(),
				Name:        p.Name(),
				Type:        p.Type(),
				Version:     p.Version(),
				Description: p.Description(),
			}
			return info
		}
	}
	return nil
}

// GetAllPluginInfos 获取所有插件信息
func (a *WasmPluginManagerActor) GetAllPluginInfos() []*PluginInfo {
	var infos []*PluginInfo
	for _, p := range a.plugins {
		info := &PluginInfo{
			ID:          p.ID(),
			Name:        p.Name(),
			Type:        p.Type(),
			Version:     p.Version(),
			Description: p.Description(),
		}
		infos = append(infos, info)
	}
	return infos
}

// HandleGetPluginMessage 处理获取插件消息
func (a *WasmPluginManagerActor) HandleGetPluginMessage(msg *GetPluginMessage) (*GetPluginResponse, error) {
	for _, p := range a.plugins {
		if p.ID() == msg.PluginID {
			return &GetPluginResponse{
				Plugin: p,
			}, nil
		}
	}
	return nil, fmt.Errorf("plugin not found: %s", msg.PluginID)
}

// HandleGetAllPluginsMessage 处理获取所有插件消息
func (a *WasmPluginManagerActor) HandleGetAllPluginsMessage(msg *GetAllPluginsMessage) (*GetAllPluginsResponse, error) {
	a.mu.RLock()
	defer a.mu.RUnlock()

	pluginInfos := make([]PluginInfo, 0, len(a.plugins))

	for _, p := range a.plugins {
		pluginInfos = append(pluginInfos, PluginInfo{
			ID:          p.ID(),
			Name:        p.Name(),
			Type:        p.Type(),
			Version:     p.Version(),
			Description: p.Description(),
		})
	}

	return &GetAllPluginsResponse{
		PluginInfos: pluginInfos,
	}, nil
}
